import os
from utils.thread.thread import thread_del
from utils.thread.thread import thread_run
from utils.thread.thread import thread_timer_add
from utils.thread.thread import thread_except_add
from utils.thread.thread import thread_write_add
from utils.thread.thread import thread_read_add
import struct
import socket
from local_log import logger


def is_valid_ip(ip):
    sa = ip.split('.')
    if len(sa) != 4:
        return False
    for it in sa:
        if int(it) < 0 or int(it) > 255:
            return False
    return True


def get_wan_info():
    try:
        with os.popen('route -n 2>&1') as f:
            lines = f.readlines()
            if len(lines) > 3:
                line = lines[2]
                linea = line.split()
                if len(linea) >= 8:
                    ip = linea[1]
                    inf = linea[7]
                    if is_valid_ip(ip):
                        return ip, inf
        with os.popen('ip route show 2>&1') as f:
            lines = f.readlines()
            if len(lines) > 1:
                line = lines[0]
                linea = line.split()
                if len(linea) >= 5:
                    desc = linea[0]
                    ip = linea[2]
                    inf = linea[4]
                    if desc == 'default' and is_valid_ip(ip):
                        return ip, inf
        return None, None
    except Exception as e:
        logger.debug(f'get wan info err {e}')
        return None, None


class Notify(object):
    def __init__(self):
        logger.debug(f'enter notify !!!!!!!!!!!!!!!!!!!!!!!')
        super().__init__()
        self._notify_addr = ('127.0.0.1', 8000)
        self._notify_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        logger.debug(f'get notif socket is {self._notify_socket}')
        self._notify_socket.bind(self._notify_addr)
        self._notify_socket.setblocking(False)
        self._th_read = None
        self._reset_read()

    def _reset_read(self):
        if self._th_read:
            thread_del(self._th_read)
            self._th_read = None
        thread_read_add(
            Notify._notify_read,
            self,
            self._notify_socket.fileno())

    @staticmethod
    def _notify_read(local, fd, args):
        local._th_read = None
        local._reset_read()

        data, addr = local._notify_socket.recvfrom(4096)
        local.notify_proc(data)

    def notify(self, data: bytes = bytes(1)):
        try:
            ts = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            ts.sendto(data, self._notify_addr)
            ts.close()
        except BaseException:
            pass

    def notify_proc(self, data: bytes):
        logger.debug(f'it is err when goto here !!!!!!!!!!!!!!!!!!!!!!!!!!')
